package jmine.tec.sync.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import jmine.tec.persist.annotation.Alias;
import jmine.tec.persist.annotation.Index;
import bancosys.tec.component.Documentation;
import bancosys.tec.persist.Persistable;
import bancosys.tec.persist.bussobj.PersistableBusinessObject;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.utils.reflection.ReflectionUtils;

/**
 * @author takeshi
 */
@Entity
@Alias("REMENT")
@Table(name = "REMOTE_ENTITY")
@SequenceGenerator(name = "SEQ_REMENT", sequenceName = "SEQ_REMENT")
@Documentation("ARMAZENA A REFERENCIA CRUZADA DE UMA ENTIDADE PARA A FONTE DO SISTEMA REMOTO")
@Index(suffix = "JT_0", columns = { "REMOTE_ENTITY_NAME", "ORIGINAL_ID", "SOURCE" })
public class RemoteEntityReference extends PersistableBusinessObject {

    public static final int MAX_SOURCE_SIZE = 32;

    private Long id;

    private String source;

    private Long remoteEntityId;

    private Long localEntityId;

    private String localEntityName, remoteEntityName;

    private Long lastRemoteVersion;

    /**
     * @return Long
     */
    @Id
    @Column(name = "COD_REMOTE_ENTITY")
    @Documentation("CODIGO DO REMOTE ENTITY")
    @GeneratedValue(generator = "SEQ_REMENT")
    public Long getId() {
        return this.id;
    }

    /**
     * @return {@link String}
     */
    @Column(name = "SOURCE", length = MAX_SOURCE_SIZE)
    @Documentation("ARMAZENA O NOME DO SISTEMA DE ORIGEM")
    public String getSource() {
        return this.source;
    }

    /**
     * @param source String
     */
    public void setSource(String source) {
        this.source = source;
    }

    /**
     * @return Long
     */
    @Column(name = "ORIGINAL_ID")
    @Documentation("ARMAZENA O ID ORIGINAL DO SISTEMA DE ORIGEM")
    public Long getRemoteEntityId() {
        return this.remoteEntityId;
    }

    /**
     * @param originalId Long
     */
    public void setRemoteEntityId(Long originalId) {
        this.remoteEntityId = originalId;
    }

    /**
     * @param id Long
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return {@link String}
     */
    @Column(name = "ENTITY_NAME")
    @Documentation("ARMAZENA O NOME DA ENTIDADE DO SISTEMA LOCAL")
    public String getLocalEntityName() {
        return this.localEntityName;
    }

    /**
     * @param entityName {@link String}
     */
    public void setLocalEntityName(String entityName) {
        this.localEntityName = entityName;
    }

    /**
     * @return Long
     */
    @Column(name = "ENTITY_ID")
    @Documentation("ARMAZENA O ID DA ENTIDADE NO SISTEMA LOCAL")
    public Long getLocalEntityId() {
        return this.localEntityId;
    }

    /**
     * @param entityId Long
     */
    public void setLocalEntityId(Long entityId) {
        this.localEntityId = entityId;
    }

    /**
     * @return Class
     */
    @Transient
    @SuppressWarnings("unchecked")
    public Class<? extends Persistable> remoteClass() {
        try {
            return (Class<? extends Persistable>) ReflectionUtils.findClass(this.localEntityName);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * @return {@link Persistable}
     * @throws BeanNotFoundException bnf
     */
    public Persistable recoverLocalCopy() throws BeanNotFoundException {
        BaseDAO<Persistable> genericDAO = this.getController().getDAOFactory().getGenericDAO(this.remoteClass());
        return genericDAO.findByPk(this.localEntityId);
    }

    /**
     * @return {@link String}
     */
    @Column(name = "REMOTE_ENTITY_NAME")
    @Documentation("ARMAZENA O NOME DA ENTIDADE DO SISTEMA DE ORIGEM")
    public String getRemoteEntityName() {
        return this.remoteEntityName;
    }

    /**
     * @param remoteEntityName {@link String}
     */
    public void setRemoteEntityName(String remoteEntityName) {
        this.remoteEntityName = remoteEntityName;
    }

    /**
     * @return the lastKnownVersion
     */
    @Column(name = "VERSION")
    @Documentation("ARMAZENA O VALOR DA ULTIMA VERSAO DO SISTEMA DE ORIGEM")
    public Long getLastRemoteVersion() {
        return this.lastRemoteVersion;
    }

    /**
     * @param lastKnownVersion the lastKnownVersion to set
     */
    public void setLastRemoteVersion(Long lastKnownVersion) {
        this.lastRemoteVersion = lastKnownVersion;
    }

}
